/**
 * =============================================================================
 * 捷伴智慧健康 AI 流式对话组件
 * =============================================================================
 * 
 * 版权声明：
 * 作者：衡森
 * QQ：191118032
 * 微信：huangsentianzhenkeai
 * 
 * 平台支持：仅支持微信小程序
 * 
 * 功能特性：
 * - ✅ 真实流式输出（基于微信小程序 enableChunked API）
 * - 🎤 语音识别输入（长按麦克风按钮）
 * - 🔊 AI 语音播报（回答完成后自动播放）
 * - 🔄 流式/普通模式切换
 * - 📝 本地对话记录查看
 * 
 * 使用说明：
 * 1. 必须在 app.config.ts 中配置微信同声传译插件
 * 2. 替换下方的 API Token 为你自己的
 * 3. 确保微信小程序基础库版本 >= 2.20.1
 * 
 * =============================================================================
 */

import React, { useState, useEffect } from 'react';
import { View, Text, Input, Button, ScrollView } from '@tarojs/components';
import Taro, { useLoad } from '@tarojs/taro';
import { streamChatHelper } from '../../utils/streamChatHelper';
import './index.less';

interface Message {
  id: string;
  type: 'user' | 'ai';
  content: string;
  timestamp: number;
  isStreaming?: boolean;
}

interface Stats {
  tokens?: number;
  duration?: number;
  model?: string;
}

const ChatTest: React.FC = () => {
  const [messages, setMessages] = useState<Message[]>([]);
  const [inputValue, setInputValue] = useState('');
  const [loading, setLoading] = useState(false);
  const [systemPrompt, setSystemPrompt] = useState('您好，捷伴智慧健康助手。');
  const [conversationId, setConversationId] = useState<number | null>(null);
  const [stats, setStats] = useState<Stats | null>(null);
  const [streamMode, setStreamMode] = useState(true); // 是否使用流式模式
  const [scrollIntoViewId, setScrollIntoViewId] = useState<string>('');
  const [isRecording, setIsRecording] = useState(false); // 是否正在录音
  const [recognitionManager, setRecognitionManager] = useState<any>(null);
  const [innerAudioContext] = useState(() => Taro.createInnerAudioContext());
  const [autoPlayEnabled, setAutoPlayEnabled] = useState(true); // 是否自动播放AI回答
  const [isPlaying, setIsPlaying] = useState(false); // 是否正在播放

  // 自动滚动到最新消息
  useEffect(() => {
    if (messages.length > 0) {
      const lastMessage = messages[messages.length - 1];
      // 使用 setTimeout 确保 DOM 更新后再滚动
      setTimeout(() => {
        setScrollIntoViewId(lastMessage.id);
      }, 50);
    }
  }, [messages]);

  useLoad(() => {
    // 添加欢迎消息
    addMessage('你好！我是捷伴智慧健康智能助手，有什么可以帮助你的吗？\n\n💡 支持功能：\n- ✅ 真实流式输出\n- 🔄 流式/普通模式切换\n- 🎤 语音识别输入（按住麦克风按钮）\n- 🔊 AI语音播报（回答完成后自动播放）\n- 📝 本地对话记录查看\n- 🆕 随时开始新对话', 'ai');

    // 初始化语音识别管理器
    initRecognitionManager();

    // 初始化音频播放器
    initAudioContext();
  });

  // 初始化语音识别管理器
  const initRecognitionManager = () => {
    try {
      // 在小程序环境中使用插件
      if (process.env.TARO_ENV === 'weapp') {
        // @ts-ignore
        const plugin = requirePlugin('WechatSI');
        const manager = plugin.getRecordRecognitionManager();

        // 监听识别开始
        manager.onStart = (res) => {
          console.log('开始识别', res);
          setIsRecording(true);
        };

        // 监听识别结束
        manager.onStop = (res) => {
          console.log('识别结束', res);
          setIsRecording(false);

          if (res.result) {
            setInputValue(res.result);
            Taro.showToast({
              title: '识别成功',
              icon: 'success',
              duration: 1000
            });
          } else {
            Taro.showToast({
              title: '未识别到内容',
              icon: 'none',
              duration: 2000
            });
          }
        };

        // 监听识别错误
        manager.onError = (err) => {
          console.error('识别错误', err);
          setIsRecording(false);

          let errorMsg = '识别失败，请重试';
          if (err.errMsg) {
            if (err.errMsg.includes('auth deny')) {
              errorMsg = '请允许录音权限';
            } else if (err.errMsg.includes('timeout')) {
              errorMsg = '识别超时，请重试';
            } else if (err.errMsg.includes('network')) {
              errorMsg = '网络错误，请检查网络';
            }
          }

          Taro.showToast({
            title: errorMsg,
            icon: 'none',
            duration: 2000
          });
        };

        // 监听实时识别结果（可选）
        manager.onRecognize = (res) => {
          console.log('实时识别结果：', res.result);
        };

        setRecognitionManager(manager);
      }
    } catch (error) {
      console.error('初始化识别管理器失败', error);
    }
  };

  // 开始录音和识别
  const startRecord = () => {
    if (!recognitionManager) {
      Taro.showToast({
        title: '语音识别未初始化',
        icon: 'none',
        duration: 2000
      });
      return;
    }

    // 检查录音授权
    Taro.getSetting({
      success: (res) => {
        if (res.authSetting['scope.record'] === false) {
          // 用户拒绝过授权，引导用户开启
          Taro.showModal({
            title: '需要录音权限',
            content: '请在设置中开启录音权限',
            success: (modalRes) => {
              if (modalRes.confirm) {
                Taro.openSetting();
              }
            }
          });
          return;
        }

        try {
          // 开始识别（会自动录音）
          recognitionManager.start({
            duration: 60000,  // 最长录音时间60秒
            lang: 'zh_CN'     // 中文识别
          });

          Taro.showToast({
            title: '开始录音识别...',
            icon: 'none',
            duration: 1000
          });
        } catch (error) {
          console.error('启动识别失败', error);
          Taro.showToast({
            title: '启动失败，请重试',
            icon: 'none',
            duration: 2000
          });
        }
      }
    });
  };

  // 停止录音和识别
  const stopRecord = () => {
    if (recognitionManager && isRecording) {
      try {
        recognitionManager.stop();
      } catch (error) {
        console.error('停止识别失败', error);
        setIsRecording(false);
      }
    }
  };

  // 初始化音频播放器
  const initAudioContext = () => {
    // 监听音频播放结束
    innerAudioContext.onEnded(() => {
      console.log('音频播放结束');
      setIsPlaying(false);
    });

    // 监听音频播放错误
    innerAudioContext.onError((err) => {
      console.error('音频播放错误', err);
      setIsPlaying(false);
      Taro.showToast({
        title: '播放失败',
        icon: 'none',
        duration: 2000
      });
    });

    // 监听音频停止
    innerAudioContext.onStop(() => {
      console.log('音频停止');
      setIsPlaying(false);
    });
  };

  // 播放AI回答的语音
  const playAIResponse = (text: string) => {
    if (!autoPlayEnabled || !text || !text.trim()) {
      console.log('跳过播放：', { autoPlayEnabled, hasText: !!text });
      return;
    }

    console.log('开始播放AI回答，文本长度:', text.length);

    try {
      if (process.env.TARO_ENV === 'weapp') {
        // @ts-ignore
        const plugin = requirePlugin('WechatSI');

        setIsPlaying(true);

        // 调用插件的文字转语音接口
        plugin.textToSpeech({
          lang: 'zh_CN',
          tts: true,
          content: text,
          success: (res) => {
            console.log('语音合成成功');

            if (res.filename) {
              // 播放合成的语音
              innerAudioContext.src = res.filename;
              innerAudioContext.play();

              console.log('开始播放语音');
            } else {
              console.log('没有返回音频文件');
              setIsPlaying(false);
            }
          },
          fail: (err) => {
            console.error('语音合成失败:', err);
            setIsPlaying(false);

            let errorMsg = '语音合成失败';
            if (err.errMsg) {
              if (err.errMsg.includes('auth')) {
                errorMsg = '没有语音合成权限';
              } else if (err.errMsg.includes('network')) {
                errorMsg = '网络错误';
              } else if (err.errMsg.includes('exceed')) {
                errorMsg = '文字过长';
              }
            }

            Taro.showToast({
              title: errorMsg,
              icon: 'none',
              duration: 2000
            });
          }
        });
      } else {
        console.log('非小程序环境，无法播放');
        setIsPlaying(false);
      }
    } catch (error) {
      console.error('语音合成调用失败', error);
      setIsPlaying(false);
    }
  };

  // 停止播放
  const stopPlaying = () => {
    console.log('停止语音播放');
    if (innerAudioContext) {
      innerAudioContext.stop();
    }
    setIsPlaying(false);
  };

  // 添加消息到对话列表
  const addMessage = (content: string, type: 'user' | 'ai', isStreaming: boolean = false) => {
    const newMessage: Message = {
      id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      type,
      content,
      timestamp: Date.now(),
      isStreaming
    };
    setMessages(prev => [...prev, newMessage]);
  };

  // 更新最后一条AI消息的内容（用于流式输出）
  const updateLastAIMessage = (content: string, isComplete: boolean = false) => {
    setMessages(prev => {
      const newMessages = [...prev];
      const lastIndex = newMessages.length - 1;

      if (lastIndex >= 0 && newMessages[lastIndex]?.type === 'ai') {
        // 创建新对象而不是修改原对象，避免 React 渲染问题
        newMessages[lastIndex] = {
          ...newMessages[lastIndex],
          content: content,
          isStreaming: !isComplete
        };

        // 如果流式输出完成，自动播放完整回答
        if (isComplete && autoPlayEnabled && content.trim()) {
          console.log('AI回答完成，准备播放');
          // 延迟一小段时间再播放，确保状态已更新
          setTimeout(() => {
            playAIResponse(content);
          }, 300);
        }
      }

      return newMessages;
    });
  };

  // 发送消息
  const sendMessage = async () => {
    if (!inputValue.trim() || loading) return;

    const userMessage = inputValue;
    setInputValue('');
    addMessage(userMessage, 'user');
    setLoading(true);

    // 停止当前播放
    stopPlaying();

    try {
      if (streamMode) {
        // 流式输出模式
        addMessage('', 'ai', true);

        await streamChatHelper.streamChat(
          userMessage,
          conversationId || undefined,
          (displayedContent: string, isComplete: boolean) => {
            // 真正的流式输出，实时显示
            if (displayedContent) {
              updateLastAIMessage(displayedContent, isComplete);
            }
          },
          (error: any) => {
            console.error('流式请求错误:', error);
            updateLastAIMessage('抱歉，网络连接出现问题，请稍后重试。', true);
          },
          (convId: number) => {
            // 保存会话ID
            if (!conversationId) {
              setConversationId(convId);
            }
          },
          (statsData: any) => {
            // 保存统计信息
            setStats(statsData);
          }
        );
      } else {
        // 普通模式
        const result = await streamChatHelper.chat(
          userMessage,
          conversationId || undefined
        );

        // 处理响应
        if (result?.conversation && !conversationId) {
          setConversationId(result.conversation);
        }

        if (result?.stats) {
          setStats(result.stats);
        }

        let content = '';
        if (result?.chunks && Array.isArray(result.chunks)) {
          content = result.chunks.map((c: any) => c.content).join('');
        } else if (result?.content) {
          content = result.content;
        }

        addMessage(content || '未获取到响应', 'ai');
      }

    } catch (error) {
      console.error('API调用失败:', error);
      if (streamMode) {
        updateLastAIMessage('网络连接出现问题，请检查网络后重试。', true);
      } else {
        addMessage('网络连接出现问题，请检查网络后重试。', 'ai');
      }
    } finally {
      setLoading(false);
    }
  };

  // 清除对话
  const clearChat = () => {
    stopPlaying();
    setMessages([]);
    setConversationId(null);
    setStats(null);
    addMessage('对话已清除，开始新的会话吧！', 'ai');
  };

  // 切换自动播放
  const toggleAutoPlay = () => {
    const newState = !autoPlayEnabled;
    setAutoPlayEnabled(newState);

    if (!newState) {
      // 关闭自动播放时，停止当前播放
      stopPlaying();
    }

    Taro.showToast({
      title: newState ? '已开启语音播报' : '已关闭语音播报',
      icon: 'none',
      duration: 1500
    });
  };

  // 查看本地历史记录（API不支持，使用本地数据）
  const viewLocalHistory = () => {
    if (messages.length === 0) {
      Taro.showToast({
        title: '暂无对话记录',
        icon: 'none',
        duration: 2000
      });
      return;
    }

    // 格式化显示当前对话历史
    const content = messages.map((msg, index) => {
      const role = msg.type === 'user' ? '👤 用户' : '🤖 AI';
      const time = new Date(msg.timestamp).toLocaleString('zh-CN');
      return `${index + 1}. ${role} [${time}]\n${msg.content}`;
    }).join('\n\n---\n\n');

    Taro.showModal({
      title: `当前对话记录 (${messages.length}条)`,
      content: content.length > 500 ? content.substring(0, 500) + '...\n\n(内容过长，已截断)' : content,
      showCancel: true,
      confirmText: '确定',
      cancelText: '复制全部',
      success: (res) => {
        if (res.cancel) {
          // 用户点击了"复制全部"
          Taro.setClipboardData({
            data: content,
            success: () => {
              Taro.showToast({
                title: '已复制到剪贴板',
                icon: 'success'
              });
            }
          });
        }
      }
    });
  };

  // 切换流式模式
  const toggleStreamMode = () => {
    setStreamMode(!streamMode);
    Taro.showToast({
      title: streamMode ? '切换到普通模式' : '切换到流式模式',
      icon: 'none'
    });
  };

  return (
    <View className='chat-test'>
      <View className='header'>
        <Text className='title'>捷伴智慧健康 AI对话</Text>
        <View className='actions'>
          <Button className='btn secondary' onClick={toggleAutoPlay} disabled={loading}>
            {autoPlayEnabled ? '🔊开启' : '🔇关闭'}
          </Button>
          <Button className='btn secondary' onClick={toggleStreamMode} disabled={loading}>
            {streamMode ? '🔄流式' : '📝普通'}
          </Button>
          <Button className='btn secondary' onClick={viewLocalHistory} disabled={loading || messages.length === 0}>
            📝记录
          </Button>
          <Button className='btn secondary' onClick={clearChat} disabled={loading}>
            🆕新对话
          </Button>
        </View>
      </View>

      <View className='system-prompt'>
        <Text className='label'>系统提示词:</Text>
        <Input
          className='system-input'
          value={systemPrompt}
          onInput={e => setSystemPrompt(e.detail.value)}
          placeholder='设置AI的角色和行为...'
        />
      </View>

      <ScrollView
        className='messages'
        scrollY
        scrollIntoView={scrollIntoViewId}
        scrollWithAnimation
      >
        {messages.map(message => (
          <View key={message.id} id={message.id} className={`message ${message.type}`}>
            <View className='avatar'>
              {message.type === 'user' ? '👤' : '🤖'}
            </View>
            <View className='content'>
              <Text className='text'>
                {message.content}
              </Text>
              <Text className='time'>
                {new Date(message.timestamp).toLocaleTimeString()}
              </Text>
            </View>
          </View>
        ))}
        {loading && (
          <View className='message ai'>
            <View className='avatar'>🤖</View>
            <View className='content'>
              <Text className='text'>正在思考中...</Text>
            </View>
          </View>
        )}
      </ScrollView>

      <View className='input-area'>
        <Button
          className='voice-btn'
          onTouchStart={startRecord}
          onTouchEnd={stopRecord}
          disabled={loading}
        >
          {isRecording ? '🔴 录音中...' : '🎤'}
        </Button>
        <Input
          className='input'
          value={inputValue}
          onInput={e => setInputValue(e.detail.value)}
          placeholder='请输入您的问题...'
          disabled={loading}
          onConfirm={sendMessage}
        />
        {isPlaying && (
          <Button
            className='stop-voice-btn'
            onClick={stopPlaying}
          >
            ⏹️
          </Button>
        )}
        <Button
          className='send-btn'
          onClick={sendMessage}
          disabled={loading || !inputValue.trim()}
        >
          发送
        </Button>
      </View>

      <View className='status'>
        <Text className='status-text'>
          {loading ? '⏳ 处理中...' : '✅ 就绪'} |
          {isPlaying ? '🔊 播放中' : autoPlayEnabled ? '🔊 自动播放' : '🔇 静音'} |
          💬 消息: {messages.length} |
          🆔 会话: {conversationId || '未建立'} |
          {streamMode ? '🔄 真实流式' : '📝 普通模式'}
          {stats && stats.tokens && ` | 🔢 Tokens: ${stats.tokens}`}
          {stats && stats.model && ` | 🤖 ${stats.model}`}
        </Text>
      </View>
    </View>
  );
};

export default ChatTest;

